/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2012/11/30
* File: EnnResource.h
**/

#ifndef EnnResource_h__
#define EnnResource_h__

#include <EnnPrerequisites.h>

namespace Enn
{
	class ResourceManager;
	typedef unsigned long long int ResourceHandle;
	class _EnnExport Resource : public ResourceAlloc
	{
	public:
		enum LoadingState
		{
			LOADSTATE_UNLOADED,
			LOADSTATE_LOADED_FAILURE,
			LOADSTATE_LOADED_SUCCESS,
		};
		class Listener
		{
		public:
			Listener() {}
			virtual ~Listener() {}

			virtual void loadState(Resource* res, LoadingState state)
			{

			}
		};

	public:
		Resource(ResourceManager* mgr, 
			const String& name, 
			const String& group,
			ResourceHandle handle);

		virtual ~Resource();

		virtual void load(bool backgroundThread = false);

		virtual void reload(void);

		virtual void unload(void);

		virtual size_t getSize(void) const
		{ 
			return _size_in_bytes; 
		}

		virtual void touch(void);

		virtual const String& getName(void) const 
		{ 
			return _name; 
		}

		virtual ResourceHandle getHandle(void) const
		{
			return _handle;
		}

		virtual bool isLoadedSuccess(void) const
		{
			return _res_state == LOADSTATE_LOADED_SUCCESS;
		}

		virtual LoadingState getLoadingState() const
		{
			return _res_state;
		}

		virtual void addListener(Listener* lis);

		virtual void removeListener(Listener* lis);

		virtual const String& getGroup(void) const { return _group; }

		virtual ResourceManager* getResourceManager(void) { return _mgr; }

	protected:
		virtual void loadImpl(void) = 0;

		virtual void unloadImpl(void) = 0;

	protected:
		ResourceManager*	_mgr;
		String				_name;
		String				_group;
		ResourceHandle		_handle;
		LoadingState		_res_state;
		size_t				_size_in_bytes;

		typedef				set<Listener*>::type ListenerList;
		ListenerList		_listener_list;
	};

	typedef SharedPtr<Resource>::type ResourcePtr;
}
#endif    /* EnnResource_h__ */